
// Define SudokuUI object if it is not already defined
if (typeof SudokuUI === 'undefined') var SudokuUI = {};

// Constants
SudokuUI.input = 
{
	wheelTolerence : 20, // Ignore multiple wheel events within this number of milliseconds.

	LastWheelPoll : new Date(),
	// Mouse position
	HoverRow : null,
	HoverCol : null,

	// Hook document events
	init : function ()
	{
		var objTable = document.getElementById('sudoku_grid');

		// Register keydown event
		if (document.addEventListener)
			document.addEventListener('keydown', SudokuUI.input.key_handler, false);
		else if (document.attachEvent)
			document.attachEvent('onkeydown', SudokuUI.input.key_handler);
		else
			document.onkeydown = SudokuUI.input.key_handler;

		// Register mousewheel event
		if (objTable.addEventListener)
		{
			// Gecko engine names this event differently. Use XUL to detect Gecko browser.
			if (window.XULElement)
				objTable.addEventListener('DOMMouseScroll', SudokuUI.input.wheel_handler, false);
			else 
				objTable.addEventListener('mousewheel', SudokuUI.input.wheel_handler, false);
		}
		else if (objTable.attachEvent)
			objTable.attachEvent('onmousewheel', SudokuUI.input.wheel_handler);
		else
			objTable.onmousewheel = SudokuUI.input.wheel_handler;
	},

	// Cursor hovers over a cell
	mousein_handler : function (evt)
	{
		SudokuUI.input.HoverRow = this.r;
		SudokuUI.input.HoverCol = this.c;
	},

	// Cursor leaves the grid
	mouseout_handler : function (evt)
	{
		SudokuUI.input.HoverRow = null;
		SudokuUI.input.HoverCol = null;
	},

	key_handler : function (evt)
	{
		// Exit if cursor is outside of the sudoku puzzle
		if (SudokuUI.input.HoverRow === null) return;

		// Browser compatibility code
		if (!evt) var evt = window.event;

		var keycode, NumberPressed;

		if (evt.keyCode) keycode = evt.keyCode;
		else if (evt.which) keycode = evt.which;

		// console.log('Keypress (' + keycode + ')');

		// user pressed 0 - 9 in the QWERTY portion of the keyboard
		if (48 <= keycode && keycode <= 57) NumberPressed = keycode - 48;
		// user pressed 0 - 9 in the keypad portion of the keyboard
		else if (96 <= keycode && keycode <= 105) NumberPressed = keycode - 96;
		// user pressed delete key
		else if (keycode === 46) NumberPressed = 0;
		// user did not press anything we can use
		else return; // exit function so we can cancel the other event cases.

		FillCellValue (SudokuUI.input.HoverRow, SudokuUI.input.HoverCol, NumberPressed);

		// Cancel default event
		if (evt.preventDefault) evt.preventDefault();
		else evt.returnValue = false;
	},

	// Convert mouse wheel events to positive and negative. 
	wheel_handler : function (evt)
	{
		// Exit if cursor is outside of the sudoku puzzle or over a locked cell
		if (SudokuUI.input.HoverRow === null) return;

		if (!evt) var evt = window.event;

		// Ignore consecutive wheel events within a short period
		var Now = new Date();
		if (Now.getTime() < SudokuUI.input.wheelTolerence + SudokuUI.input.LastWheelPoll.getTime()) return;
		SudokuUI.input.LastWheelPoll = Now;

		var ScrollDirection; // up = positive, down = negative

		// Get wheel delta
		// evt.wheelDelta is for IE
		// evt.detail is for Netscape-based
		ScrollDirection = ((evt.wheelDelta ? evt.wheelDelta : -evt.detail) >= 0 ? 1 : -1);

		ScrollThruPossibles(SudokuUI.input.HoverRow, SudokuUI.input.HoverCol, ScrollDirection)

		// console.log ('Wheel ' + ((ScrollDirection + 1) ? 'up' : 'down') + ' (Delta: ' + (evt.wheelDelta ? evt.wheelDelta : evt.detail) + ')');

		// Cancel default event
		if (evt.preventDefault) evt.preventDefault();
		else evt.returnValue = false;
	}
}